package com.yx.changdao.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yx.changdao.common.annotation.AutoLog;
import com.yx.changdao.common.annotation.ShiroDesc;
import com.yx.changdao.common.data.Pager;
import com.yx.changdao.common.data.Result;
import com.yx.changdao.common.entity.Department;
import com.yx.changdao.common.entity.SysRole;
import com.yx.changdao.common.entity.SysUser;
import com.yx.changdao.common.entity.SysUserRole;
import com.yx.changdao.common.exception.AlertException;
import com.yx.changdao.common.utils.MD5Utils;
import com.yx.changdao.common.utils.PinyinUtils;
import com.yx.changdao.common.utils.SysConst;
import com.yx.changdao.common.utils.SysUtils;
import com.yx.changdao.common.valid.Default;
import com.yx.changdao.common.valid.Update;
import com.yx.changdao.service.DepartmentService;
import com.yx.changdao.service.SysRoleService;
import com.yx.changdao.service.SysUserRoleService;
import com.yx.changdao.service.SysUserService;
import org.apache.logging.log4j.util.Strings;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.hibernate.validator.constraints.Length;
import org.nutz.json.Json;
import org.nutz.mvc.annotation.POST;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * 用户接口
 * <p>
 * <br />
 *
 * @Auther: Zhangjiashun
 * @create 2019/11/6 15:58
 */
@RestController
@RequestMapping("/sys/user")
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    SysUserRoleService sysUserRoleService;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private SysRoleService sysRoleService;


    /**
     * 用户列表  当只传页码时默认每页 15 条
     *
     * @param page  页码
     * @param limit 每页条数
     * @return
     * @throws AlertException
     */
    @AutoLog
    @GetMapping({"/list"})
    @RequiresPermissions("sys:user:list")
    @ShiroDesc("系统用户:列表")
    public Result list(@RequestParam(value = "page") Long page,
                       @RequestParam(value = "limit", required = false) Integer limit) throws AlertException {
        if (limit == null) {
            // 如果传入每页条数为空 默认取 15
            limit = SysConst.LIMIT_PAGE;
        }
        // 分页配置
        Page<SysUser> pager = new Page<>(page, limit);
        // 根据请求解析条件。
        QueryWrapper<SysUser> queryWrapper = SysUtils.autoCnd(SysUser.class);
        // 获取分页结果集。 排除admin
        IPage<SysUser> userPage = this.sysUserService.page(pager, queryWrapper.ne(SysUser.USERNAME, SysConst.SYS_LOGIN_NAME));

        // 所有符合条件的用户
        List<SysUser> sysUserList = userPage.getRecords();
        // 获取用户对应的角色
        List<SysUser> users = getUserAndRoles(sysUserList);

        Map<String, Object> map = new HashMap();
        map.put("list", users);
        map.put("pager", new Pager(userPage));
        return Result.ok().data(map);
    }

    /**
     * 角色列表下拉框
     *
     * @return Result
     */
    @AutoLog
    @GetMapping("/role/select")
    public Result roleSelect() {
        List<SysRole> list = sysRoleService.list(new QueryWrapper<SysRole>().ne(SysRole.ROLE_ID, SysConst.SYS_ROLE));
        ArrayList<Map<String, Object>> mapArrayList = new ArrayList<>();
        for (SysRole sysRole : list) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("roleName", sysRole.getRoleName());
            map.put("roleId", sysRole.getRoleId());
            mapArrayList.add(map);
        }
        return Result.ok().data(mapArrayList);
    }

    /**
     * 部门下拉列表
     *
     * @param
     * @return Result
     */
    @AutoLog
    @GetMapping("/dep/select")
    public Result select() {
        List<Department> departments = departmentService.list();
        ArrayList<Map<String, Object>> mapArrayList = new ArrayList<>();
        for (Department department : departments) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("depId", department.getDepId());
            map.put("depName", department.getDepName());
            mapArrayList.add(map);
        }
        return Result.ok().data(mapArrayList);
    }

    /**
     * 添加用户
     *
     * @param user 待添加用户
     * @return
     * @throws AlertException
     */
    @AutoLog
    @PostMapping
//    @RequiresPermissions("sys:user:add")
//    @ShiroDesc("系统用户:添加")
    public Result add(@RequestBody @Validated(Default.class) SysUser user) throws AlertException {
        this.sysUserService.addUser(user);
        return Result.ok("用户添加成功");
    }

    /**
     * 更新用户
     *
     * @param user 需要更新的用户。
     * @return
     * @throws AlertException
     */
    @AutoLog
    @PutMapping
//    @RequiresPermissions("sys:user:save")
//    @ShiroDesc("系统用户:保存")
    public Result update(@RequestBody @Validated(Update.class) SysUser user) throws AlertException {
        if (!this.sysUserService.updateUser(user)) {
            Result.ok("用户更新失败");
        }
        return Result.ok("用户更新成功");

    }

    /**
     * 权限校验 看是否是原始密码
     * @return
     */
    @AutoLog
    @PostMapping("/verifyPwd")
    public Result verifyPwd( @NotEmpty(message = "原密码不能为空")
                                 @Length(min = 5, max = 32, message = "密码只能在5~32位之间")
                                 @RequestParam("old") String oldPwd) throws AlertException {
        // 当前用户密码和盐
        String password = SysUtils.currentUser().getPassword();
        String salt = SysUtils.currentUser().getSalt();

        if (!MD5Utils.shiroEncryption(oldPwd, salt).equals(password)) {
            throw new AlertException("原密码错误");
        }
        return Result.ok("密码校验成功");
    }

    /**
     * 帐号列表修改密码
     */
    @AutoLog
    @PutMapping("/changePwdList")
    public Result changePwdList(
            @Length(min = 5, max = 32, message = "密码只能在5~32位之间")
            @RequestParam("onePwd") String onePwd,
            @Length(min = 5, max = 32, message = "密码只能在5~32位之间")
            @RequestParam("twoPwd") String twoPwd,
            @RequestParam("userId")String userId) throws AlertException {
        if(Strings.isBlank(onePwd)){
            throw new AlertException("新密码不能为空");
        }
        if(Strings.isBlank(twoPwd)){
            throw new AlertException("确认密码不能为空");
        }
        if(!onePwd.equals(twoPwd)){
            throw new AlertException("两次密码不一致");
        }
        SysUser userById = sysUserService.getUserById(userId);
        if(userById==null){
            throw new AlertException("该用户不存在");
        }
        this.sysUserService.changePwd(userId, onePwd);
        return Result.ok("密码修改成功");
    }

    /**
     * 修改密码
     *
     * @param oldPwd 原密码
     * @param newPwd 新密码
     * @return
     * @throws AlertException
     */
    @AutoLog
    @PutMapping("/changepwd")
    /*@RequiresPermissions("sys:user:changepwd")
    @ShiroDesc("系统用户:修改密码")*/
    public Result changepwd(
            @NotEmpty(message = "原密码不能为空")
            @Length(min = 5, max = 32, message = "密码只能在5~32位之间")
            @RequestParam("old") String oldPwd,
            @NotEmpty(message = "新密码不能为空")
            @Length(min = 5, max = 32, message = "密码只能在5~32位之间")
            @RequestParam("new") String newPwd) throws AlertException {

        // 当前用户密码和盐
        String password = SysUtils.currentUser().getPassword();
        String salt = SysUtils.currentUser().getSalt();

        if (!MD5Utils.shiroEncryption(oldPwd, salt).equals(password)) {
            throw new AlertException("原密码错误");
        }

        this.sysUserService.changePwd(SysUtils.currentUserId(), newPwd);
        return Result.ok("密码修改成功");
    }

    /**
     * 重置用户密码
     *
     * @param id 用户id
     * @return
     * @throws AlertException
     */
    @AutoLog
    @PutMapping("/resetpwd/{id}")
    @RequiresPermissions("sys:user:resetpwd")
    @ShiroDesc("系统用户:重置密码")
    public Result changeUserpwd(
            @NotEmpty(message = "用户id不能为空")
            @Length(min = 1, max = 32, message = "用户id只能在1~32位之间")
            @PathVariable("id")
                    String id) throws AlertException {
        this.sysUserService.changePwd(id, SysConst.SYS_DEFAULT_PASSWORD);
        return Result.ok("密码重置成功");
    }


    /**
     * 获得指定id 用户信息。
     *
     * @param userId 用户id
     * @return
     * @throws AlertException
     */

    @AutoLog
    @GetMapping("/{id}")
//    @RequiresPermissions("sys:user:look")
//    @ShiroDesc("系统用户:查看")
    public Result get(@PathVariable("id")
                      @Length(min = 1, max = 32, message = "用户id只能在1~32位之间")
                              String userId) throws AlertException {
        SysUser user = this.sysUserService.getUserById(userId);
        if (Objects.isNull(user)) {
            throw new AlertException("未找到用户信息");
        }
        SysUserRole userRole = sysUserRoleService.getOne(new QueryWrapper<SysUserRole>().eq(SysUserRole.USER_ID, userId));
        if (!Objects.isNull(userRole)) {
            SysRole role = sysRoleService.getOne(new QueryWrapper<SysRole>().eq(SysRole.ROLE_ID, userRole.getRoleId()));
            if (!Objects.isNull(role)) {
                user.setRoleId(role.getRoleId());
                user.setRoleName(role.getRoleName());
            }
        }
        user.setPassword(null);
        user.setSalt(null);
        return Result.ok().data(user);
    }


    /**
     * 用户锁定。
     *
     * @param userId 用户id
     * @return
     * @throws AlertException
     */
    @AutoLog
    @PutMapping("lock/{id}")
    @RequiresPermissions("sys:user:lock")
    @ShiroDesc("系统用户:锁定")
    public Result lock(@PathVariable("id")
                       @NotEmpty(message = "用户id不能为空")
                       @Length(min = 5, max = 32, message = "用户id只能在5~32位之间")
                               String userId) throws AlertException {

        // 更新用户状态
        return Result.ok(this.sysUserService.lockUser(userId) ? "用户锁定成功" : "用户解锁成功");

    }


    /**
     * 删除用户
     *
     * @param userId 待删除用户id
     * @return
     * @throws AlertException
     */
    @AutoLog
    @DeleteMapping
//    @RequiresPermissions("sys:user:del")
//    @ShiroDesc("系统用户:删除")
    public Result delete(@RequestParam("userId") String userId) throws AlertException {
        SysUser user = sysUserService.getOne(new QueryWrapper<SysUser>().eq(SysUser.USER_ID, userId));
        if (Objects.isNull(user)) {
            throw new AlertException("用户id不存在");
        }
        if (SysConst.SYS_LOGIN_NAME.equals(user.getUsername())) {
            throw new AlertException("当前用户为超级管理员，无法删除");
        }
        Boolean b = this.sysUserService.delUser(userId);
        if (!b) {
            throw new AlertException("删除用户失败");
        }
        return Result.ok("删除用户成功");
    }


    private List<SysUser> getUserAndRoles(List<SysUser> sysUserList) {
        for (SysUser user : sysUserList) {
            // 设置不返回的字段。
            user.setSalt(null);
            user.setPassword(null);
            user.setDeleteFlag(null);
            // 获取用户的所有角色。

            List<SysUserRole> list = sysUserRoleService.list(new QueryWrapper<SysUserRole>().eq(SysUserRole.USER_ID, user.getUserId()));

            if (!list.isEmpty()) {
                SysRole one = sysRoleService.getOne(new QueryWrapper<SysRole>().eq(SysRole.ROLE_ID, list.get(0).getRoleId()));
                if (!Objects.isNull(one)) {
                    user.setRoleName(one.getRoleName());
                }
            } else {
                user.setRoleName("");
            }

        }
        return sysUserList;
    }

    /**
     * 账户批量生成
     */
    @AutoLog
    @PostMapping("/saveBatchUser")
    public Result saveBatchUser(@RequestParam("controlManage")String controlManage,@RequestParam("controlCommon")String controlCommon,
                                 @RequestParam("performerManage")String performerManage,@RequestParam("performerCommon")String performerCommon) throws AlertException {
       System.out.println(Json.toJson(this.sysUserService.list()));
        Boolean aBoolean = this.sysUserService.saveBatchUser(controlManage,controlCommon,performerManage,performerCommon);
        if(aBoolean==false){
            return Result.error("新增失败");
        }
        return Result.ok("新增成功");
    }

}
